/************************************************************************
                        Data.h.h - Copyright asaf
**************************************************************************/
#ifndef DATA_H
#define DATA_H
#include <algorithm>
#include <string>
#include <list>
#include <vector>
using namespace std;
#include "Course.h"
#include "CourseLectTimeSemeter.h"
#include "StudentCourse.h"
#include "AcademicTime.h"
#include "Person.h"
#include "CoursePreRequisite.h"
#include "../Shered/Reply.h"
#include "../Shered/Request.h"
#include "../Shered/ReplyData.h"
#include "../Shered/GlobalFunctions.h"
/**
  * class Data
  * Data Base
  * all data is stored here.
  * includes stored procedures (functions) for manipulating the data and returning replays 
  */
class Data
{
public:

		// Constructors/Destructors
		//default ctor
		Data ( );
		//default dctor
		virtual ~Data ();
		
		//stored procedures for manipulating the data.
		//all stored procedures: 
		//receive Request with incoming fields to be used
		//returns Reply with reply type and formatted data (if needed)
		//replys are returned with DB_REQUEST_SUCCESS or DB_REQUEST_FAIL types (in all but login).
		//on DB_REQUEST_FAIL type:		the error msg is added.
		//on DB_REQUEST_SUCCESS type:	data to be returned is added (if needed).
		
		//checks if ID in request match one in m_personList
		//received request fields:	 user ID
		//returned in reply:		 LOGIN_SUCCESS (with fields: found user's Permission and Name) or LOGIN_FAILED
		virtual auto_ptr<Reply> checkLogin (const Request &request);
		//logout's a user, currently deprecated.
		virtual auto_ptr<Reply> personLogout (const Request &request);
		//adds a new user to m_personList
		//received request fields:	 new person data.
		//returned in reply:		 DB_REQUEST_FAIL with PERSON_ALLREADY_IN_DB (error) if new ID is in db (no duplicated ids) or DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> addNewPerson (const Request &request);
		//adds a new course to m_courseList.
		//adds two new lectures for the new course to m_courseLectList
		//received request fields:	 new course data, two lecturers ids and time for two new lectures.
		//returned in reply:		 DB_REQUEST_FAIL with COURSE_ALLREADY_IN_DB (if this course all ready taken),LECTURER1_NOT_FOUND,LECTURER2_NOT_FOUND (if LECTURERs not found) errors ;DB_REQUEST_SUCCESS 
		virtual auto_ptr<Reply> addNewCourse (const Request &request);
		//deletes a person form m_personList,m_courseLectList,m_studentCourseList by user ID
		//received request fields:	 user ID
		//returned in reply:		 DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> deletePerson (const Request &request);
		//deletes a course form m_courseList,m_courseLectList,m_studentCourseList,m_coursePreRequisiteList by course ID
		//received request fields:	 course ID
		//returned in reply:		 DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> deleteCourse (const Request &request);
		//updates user data for user by user ID
		//received request fields:	 user ID
		//returned in reply:		 DB_REQUEST_SUCCESS,DB_REQUEST_FAIL with PERSON_NOT_FOUND (error).
		virtual auto_ptr<Reply> editPerson (const Request &request);
		//register a student to a course with a lecturer on a specific time.
		//received request fields:	 user ID,course ID, Lecturer ID and lecture time
		//returned in reply:		 DB_REQUEST_FAIL with STUDENT_NOT_FOUND,LECTURER_NOT_FOUND,COURSE_NOT_FOUND,LECTURE_NOT_FOUND,COURSE_FULL,USER_INVALID_SEMESTER,PREREQUISITS_NOT_MET,STUDENT_ALLREADY_REGISTERED_TO_COURSE errors ;DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> registerStudentCourse (const Request &request);
		//create a new lecture for a course with a lecturer on a specific time.
		//received request fields:	 course ID, Lecturer ID and lecture time
		//returned in reply:		 DB_REQUEST_FAIL with LECTURER_NOT_FOUND,COURSE_NOT_FOUND,LECTURE_ALLREADY_IN_DB errors; DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> assignCourseLecturerTime (const Request &request);
		//get all courses basic data sorted by semester.
		//returned in reply:		 DB_REQUEST_SUCCESS with list of courses sorted by semester, for each course: course name,id and semester.
		virtual auto_ptr<Reply> getAllCourses ( );
		//get all data on a course.
		//received request fields:	 course ID
		//returned in reply:		 DB_REQUEST_SUCCESS with course data: course name,ID,PreRequisites, and lectures data (lecturer,time...) ;DB_REQUEST_FAIL with COURSE_NOT_FOUND error.
		virtual auto_ptr<Reply> getCourseData (const Request &request);
		//get all user data.
		//received request fields:	 user ID
		//returned in reply:		 DB_REQUEST_SUCCESS with user data: name,id,type,address,date of birth and courses taken on current user's semester (course name,lecturer); DB_REQUEST_FAIL with PERSON_NOT_FOUND error.
		virtual auto_ptr<Reply> getPersonData (const Request &request);
		//get specific semester courses basic data.
		//received request fields:	 semester num
		//returned in reply:		 DB_REQUEST_SUCCESS with list of courses, for each course: course name,id and semester ; DB_REQUEST_FAIL with NO_RECOREDS_FOUND error
		virtual auto_ptr<Reply> getCoursesForSemester (const Request &request);
		//add a prerequisit course to a course.
		//received request fields:	 course ID ,prerequisit course ID
		//returned in reply:		 DB_REQUEST_FAIL with COURSE_NOT_FOUND,PREREQUISIT_NOT_FOUND errors ;DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> addPreRequisitCourse(const Request &request);
		//mark that a user as completed a course or not.
		//received request fields:	 student ID,lecturer ID and cousre ID.
		//returned in reply:		 DB_REQUEST_FAIL with LECTURE_NOT_FOUND ;DB_REQUEST_SUCCESS
		virtual auto_ptr<Reply> setStudentCourse_Completed (const Request &request);
		

		
private:
		//list of courses.
		list <Course>m_courseList;
		//list of lectures.
		list <CourseLectTimeSemeter>m_courseLectList;
		//list of users (all types).
		list <Person>m_personList;
		//list of lectures taken by users.
		list <StudentCourse>m_studentCourseList;
		//list of prerequisite courses for courses.
		list<CoursePreRequisite>m_coursePreRequisiteList;
		//deprecated copy ctor
		Data(const Data &);
		//deprecated copy operator 
		Data &operator=(const Data &rhs);


		//inner logic functions:

		//get the list of PreRequisit courses for a specific course
		list <Course> getPreRequisitCourses(const Course &course);
		//get the list of completed courses for a specific user
		list <Course> getCompletedCourses(const Person &person);
		//check if a user as all the Prerequisits in order to register to a specific course.
		bool checkPrerequisits(const Person &person,const Course &course);
};

#endif // DATA_H